﻿using LdtJudge.DataEngine.Model.XMLConfigModel.OptimzeMode;
using LdtJudge.DataEngine.Model.XMLConfigModel.SameNodeConfigModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;

namespace LdtDataEngin.ModuleDetail.BaseModule.MultiFack
{

    /// <summary>
    /// 分人员进行取差集
    /// </summary>
    public class MultiFactExcept : MultiFactBase
    {
        /// <summary>
        /// 通用处理
        /// </summary>
        /// <param name="templateNode">模板</param>
        /// <param name="personxml">人员集合</param>
        /// <param name="xmlConfigModels">配置信息</param>
        /// <param name="nodeHandleType">同节点判定类型</param>
        /// <returns></returns>
        public override string MultiFactHandleCommon(XmlNode templateNode, Dictionary<Tuple<string, string>, XmlNode> personxml, List<SameNodeXml> xmlConfigModels, SameNodeHandleType nodeHandleType)
        {
            return "";
        }

        /// <summary>
        /// 分人员数据之间进行排除
        /// </summary>
        /// <param name="templateNode">模板节点</param>
        /// <param name="personxml">分人员数据集合</param>
        /// <param name="needExcpt">需要被排除的分人员数据</param>
        /// <param name="xmlConfigModels">配置信息</param>
        /// <param name = "nodeHandleType" > 同节点判定类型 </ param >
        /// <returns></returns>
        public Dictionary<Tuple<string, string>, XmlNode> MultiFactExceptXml(XmlNode templateNode, Dictionary<Tuple<string, string>, XmlNode> personxml, Dictionary<Tuple<string, string>, XmlNode> needExcpt, List<SameNodeXml> xmlConfigModels, SameNodeHandleType nodeHandleType)
        {
            Dictionary<Tuple<string, string>, XmlNode> keyValues = new Dictionary<Tuple<string, string>, XmlNode>();
            if (personxml.Count > 0 && needExcpt.Count > 0)
            {
                //string nodename = templateNode.Name;// "事实要素";
                string templatexml = string.Format("<{0}></{0}>", templateNode.ParentNode.Name);
                foreach (var person in personxml)
                {
                    //新建一个此案由的根节点xml
                    XmlDocument result = new XmlDocument();
                    result.LoadXml(templatexml);
                    XmlNode xmlNodeFact = result.CreateElement("事实要素");
                    result.DocumentElement.AppendChild(xmlNodeFact);
                    if (needExcpt.ContainsKey(person.Key))
                    {
                        this.ExceptNode(templateNode, person.Value, needExcpt[person.Key], xmlConfigModels, xmlNodeFact, nodeHandleType);
                        keyValues.Add(person.Key, result);
                        //personxml[person.Key] = xmlNodeFact;
                    }
                    else
                    {
                        keyValues.Add(person.Key, personxml[person.Key]);
                        //personxml[person.Key] = xmlNodeFact;
                    }
                }
            }
            return keyValues.Count > 0 ? keyValues : personxml;
        }
        /// <summary>
        /// 分人员将有异议的进行数据排除
        /// </summary>
        /// <param name="templateNode">模板节点</param>
        /// <param name="personXml">分人员有异议数据</param>
        /// <param name="confirmNode">最终认定的要素信息</param>
        /// <param name="xmlConfigModels">配置信息</param>
        /// <param name = "nodeHandleType" > 同节点判定类型 </ param >
        /// <returns></returns>
        public Dictionary<Tuple<string, string>, XmlNode> MultiFactExceptXml(XmlNode templateNode, Dictionary<Tuple<string, string>, XmlNode> personXml, XmlNode confirmNode, List<SameNodeXml> xmlConfigModels, SameNodeHandleType nodeHandleType)
        {
            Dictionary<Tuple<string, string>, XmlNode> keyValues = new Dictionary<Tuple<string, string>, XmlNode>();
            if (personXml.Count > 0 && confirmNode != null && confirmNode.ChildNodes.Count > 0)
            {
                //string nodename = templateNode.Name;// "事实要素";
                string templatexml = string.Format("<{0}></{0}>", templateNode.ParentNode.Name);
                foreach (var person in personXml)
                {
                    //新建一个此案由的根节点xml
                    XmlDocument result = new XmlDocument();
                    result.LoadXml(templatexml);
                    XmlNode xmlNodeFact = result.CreateElement("事实要素");
                    result.DocumentElement.AppendChild(xmlNodeFact);
                    this.ExceptNode(templateNode, person.Value, confirmNode, xmlConfigModels, xmlNodeFact, nodeHandleType);
                    keyValues.Add(person.Key, result);
                }
            }

            return keyValues.Count > 0 ? keyValues : personXml;
        }


        /// <summary>
        /// 最终认定要素将有异议的进行数据排除
        /// </summary>
        /// <param name="templateNode">模板节点</param>
        /// <param name="confirmNode">最终认定的要素信息</param>
        /// <param name="personXml">分人员有异议数据</param>
        /// <param name="xmlConfigModels">同节点配置信息</param>
        /// <param name="nodeHandleType">同节点判定类型</param>
        /// <returns></returns>
        public XmlDocument MultiFactExceptXml(XmlNode templateNode,XmlNode confirmNode, Dictionary<Tuple<string, string>, XmlNode> personXml,  List<SameNodeXml> xmlConfigModels, SameNodeHandleType nodeHandleType)
        {
            XmlNode identify = confirmNode;
            //新建一个此案由的根节点xml
            XmlDocument result = new XmlDocument();
            
            if (personXml.Count > 0 && confirmNode != null && confirmNode.ChildNodes.Count > 0)
            {
                foreach (var person in personXml)
                {
                    string templatexml = string.Format("<{0}></{0}>", templateNode.ParentNode.Name);
                    result.LoadXml(templatexml);
                    XmlNode xmlNodeFact = result.CreateElement("事实要素");
                    this.ExceptNode(templateNode, identify, person.Value, xmlConfigModels, xmlNodeFact, nodeHandleType);
                    identify = xmlNodeFact;
                }
                result.DocumentElement.AppendChild(identify);
            }
            else
            {
                result=(XmlDocument)confirmNode;
            }
            
            return result;
        }

        /// <summary>
        /// 进行节点的对比
        /// </summary>
        /// <param name="templateNode">模板节点</param>
        /// <param name="no1">基础节点</param>
        /// <param name="no2">被对比节点</param>
        /// <param name="xmlConfigModels">对比配置</param> 
        /// <param name="result">对比结果集合</param> 
        /// <param name="nodeHandleType">同节点判定类型</param>
        public void ExceptNode(XmlNode templateNode, XmlNode no1, XmlNode no2, List<SameNodeXml> xmlConfigModels, XmlNode result, SameNodeHandleType nodeHandleType)
        {
            foreach (XmlNode nodetemplate in templateNode.ChildNodes)
            {
                string xmlpath = base.GetXmlPath(nodetemplate);
                //默认将当前节点路径赋值节点查询路径
                string rootpath = xmlpath;
                if (templateNode.Name != "事实要素")
                {
                    rootpath = xmlpath.Substring(xmlpath.LastIndexOf('/') + 1);
                }
                List<XmlNode> nobase = no1.SelectNodes(rootpath).Cast<XmlNode>().ToList();
                List<XmlNode> nodetwo = no2.SelectNodes(rootpath).Cast<XmlNode>().ToList();
                SameNodeXml xmlConfigModel = xmlConfigModels.FirstOrDefault(con => con.XmlPath == xmlpath);
                if (nobase != null && nobase.Count > 0)
                {
                    if (nodetwo != null && nodetwo.Count > 0)
                    {//判定存在当前节点信息
                        //foreach (XmlNode no_one in nobase)
                        for (int i =0; i< nobase.Count;)
                        {
                            bool nobaseisadd = true;
                            XmlNode no_one = nobase[i];
                            foreach (XmlNode no_two in nodetwo)
                            {
                                bool issameNode = base.IsSameNode(xmlConfigModel, no_one, no_two, nodeHandleType);
                                if (issameNode)
                                {
                                    XmlNode newnod = result.OwnerDocument.ImportNode(no_one, false);
                                    //当前节点为整体处理方式
                                    if (xmlConfigModel == null || (xmlConfigModel != null && string.IsNullOrWhiteSpace(xmlConfigModel.OverAll)))
                                    {
                                        foreach (XmlAttribute attr1 in no_one.Attributes)
                                        {
                                            XmlAttribute att2 = no_two.Attributes.Cast<XmlAttribute>().ToList().FirstOrDefault(at2 => at2.Name == attr1.Name);
                                            if (att2 != null && att2.Value == attr1.Value)
                                            {//将标识属性进行添加到有异议节点中
                                                if (xmlConfigModel != null)
                                                {
                                                    var handtype = xmlConfigModel.HandleTypes.FirstOrDefault(m => m.Code.Contains(nodeHandleType.ToString()));
                                                    if (handtype != null)
                                                    {
                                                        if (!handtype.CurrentNote.Any(no => no.Name == attr1.Name))
                                                        {
                                                            newnod.Attributes.RemoveNamedItem(attr1.Name);
                                                        }
                                                    }
                                                }
                                                else
                                                {
                                                    newnod.Attributes.RemoveNamedItem(attr1.Name);
                                                }
                                            }
                                        }
                                    }
                                    result.AppendChild(newnod);
                                    //进行递归获取子节点信息
                                    this.ExceptNode(nodetemplate, no_one, no_two, xmlConfigModels, newnod, nodeHandleType);
                                    //如果是相同节点，则将遍历的集合中进行移除
                                    nobase.Remove(no_one);
                                    nobaseisadd = false;
                                }
                            }
                            if (nobaseisadd)
                            {
                                i++;
                            }

                        }

                        //将没有对比上的节点进行导入
                        foreach (XmlNode node in nobase)
                        {//如果确定不是同一个节点，则进行导入当前节点
                            XmlNode nodetemp = result.OwnerDocument.ImportNode(node, true);
                            result.AppendChild(nodetemp);
                        }
                    }
                    else
                    {//如果节点不存在
                        foreach (XmlNode node_noe in nobase)
                        {
                            XmlNode newnod = result.OwnerDocument.ImportNode(node_noe, true);
                            result.AppendChild(newnod);
                        }

                    }

                }
            }

        }

    }
}
